-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
replace pure annotations in promotion with inline #21771
replace pure annotations in promotion with inline #21771
Conversation
@nanosoldier |
It's a good change. Need to figure out the CI failures, then this should be merged. |
base/promotion.jl
Outdated
promote_type() = (@_pure_meta; Bottom) | ||
promote_type(T) = (@_pure_meta; T) | ||
promote_type(T, S, U, V...) = (@_pure_meta; promote_type(T, promote_type(S, U, V...))) | ||
promote_type() = (@_inline_meta; Bottom) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any reason to put the inline annotation here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope - so far it's been mostly an exercise of find-replace. I just wanted to quickly get it working and check with Jameson if there was a reason not to do this, but I'll tidy it up soon.
e95afce
to
b0d3f2e
Compare
Hilariously, this breaks inference on |
b0d3f2e
to
3f11961
Compare
you appear to have added an empty file called |
OK, I really have been stretched for time since I first looked at this, but everytime I have a look something confuses me. My current dilemma is that inference seems to do a poor job for
I've never seen |
42a5458
to
c2db97b
Compare
May or may not be related, but observed while looking into this: julia> @code_warntype promote_type(Int,Union{})
Variables:
#self#::Base.#promote_type
#unused#@_2::Any
#unused#@_3::Any
Body:
begin
return $(Expr(:static_parameter, 1))
end::Type{Int64}
julia> @code_warntype promote_type(Int,Union{})
Variables:
#temp#@_1
#temp#@_2
#temp#@_3
Body:
begin
return $(QuoteNode(Int64))
end::Type{Int64} Any ideas anyone why the output changes upon second invocation? (Stays that way thereafter.) |
That is interesting. Possibly related to the abused Anyway we certainly are seeing a range of behaviours - ideally we:
|
Regarding my comment, it has nothing to do with pure annotations, and occurs also outside the promotion stuff: julia> foo(::Type{T}) where {T} = T
foo (generic function with 1 method)
julia> @code_warntype foo(Int)
Variables:
#self#::#foo
#unused#::Any
Body:
begin
return $(Expr(:static_parameter, 1))
end::Type{Int64}
julia> @code_warntype foo(Int)
Variables:
#temp#@_1
#temp#@_2
Body:
begin
return $(QuoteNode(Int64))
end::Type{Int64} So, interesting, but probably unrelated. |
OK, that is interesting... |
This goes a long way: --- a/base/inference.jl
+++ b/base/inference.jl
@@ -1842,7 +1842,7 @@ function abstract_call(f::ANY, fargs::Union{Tuple{},Vector{Any}}, argtypes::V
ect
t = pure_eval_call(f, argtypes, atype, sv)
t !== false && return t
- if istopfunction(tm, f, :promote_type) || istopfunction(tm, f, :typejoin)
+ if istopfunction(tm, f, :typejoin)
return Type
elseif length(argtypes) == 2 && istopfunction(tm, f, :typename)
return typename_static(argtypes[2]) I have no idea what purpose this served, though... There are more mentions of the functions you touch here in |
c4b9875
to
0c5637d
Compare
It's avoiding inferring over those functions, since it figures if pure-eval failed, there's no point in computing (and caching) an inferred version of these functions – especially if they may get big, but have no actual useful answer. Definitely a good patch you found. With it, I had just one remaining failure (in nullable). The |
@nanosoldier |
Kicked the server: @nanosoldier |
base/promotion.jl
Outdated
@@ -161,26 +161,30 @@ function promote_type(::Type{T}, ::Type{S}) where {T,S} | |||
promote_result(T, S, promote_rule(T,S), promote_rule(S,T)) | |||
end | |||
|
|||
promote_rule(T, S) = (@_pure_meta; Bottom) | |||
# TODO: this is not hyperpure, but the pure anotation seems necessary for inference to work | |||
promote_rule(::Type{<:Any}, ::Type{<:Any}) = (@_pure_meta; Bottom) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we still need to remove the @_pure_meta
from here...
Cool. :) There's still some |
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @jrevels |
0c5637d
to
cb39d4c
Compare
Can't hurt to find out :) @nanosoldier |
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @jrevels |
Nice. Nanosoldier regressions look like noise? (If I'm reading the error bars correctly?) We do need to backport this to v0.6 - the resulting bugs from world age/pure interactions have been found in the wild, as mentioned in the OP. (@tkelman?) |
nice indeed. should be good to merge. |
would intermediate commits pass tests? if not, should be squashed |
base/promotion.jl
Outdated
@@ -161,26 +161,30 @@ function promote_type(::Type{T}, ::Type{S}) where {T,S} | |||
promote_result(T, S, promote_rule(T,S), promote_rule(S,T)) | |||
end | |||
|
|||
promote_rule(T, S) = (@_pure_meta; Bottom) | |||
# TODO: this is not hyperpure, but the pure anotation seems necessary for inference to work |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is obsolete now, it seems.
cb39d4c
to
5001c6d
Compare
removes performance bug added by 0292c42
this allows printing of the Exprs flowing through inference (which might instead have the field set to something like a Const object)
Removing actually may enable inference to get a sharper result, since it is no longer being directed to ignore backedges and correctness assumptions Replaces pure annotations in promotion with inline
5001c6d
to
76a30fb
Compare
There's still something amiss here.
|
IIUC you're redefining |
Right, I missed to specify Base when I tried to change the promote_rule. This now works fine. :-)
The redefinition that caused the crash was an attempt to work around my first mistake, so I have no actual interest in that part, although a less ungraceful exit would be, well, more graceful. |
This really needs a "backport to v0.6" tag, please. |
(cherry picked from commit 15e7369) ref #21771 remove many unneeded pure annotations Removing actually may enable inference to get a sharper result, since it is no longer being directed to ignore backedges and correctness assumptions Replaces pure annotations in promotion with inline (cherry picked from commit 76a30fb) handling Base printing of Expr.typ fields not containing a Type this allows printing of the Exprs flowing through inference (which might instead have the field set to something like a Const object) (cherry picked from commit f97d9e8) apply_type on Type{T} is valid whenever T is valid removes performance bug added by 0292c42 (cherry picked from commit 8ee2e06)
This caused a test failure in Unitful.jl, cc @ajkeller34 |
Where is the Unitful error? |
It seems to me that
promote_type
is not "hyperpure" sincepromote_rule
is designed to be changed by the user at any time. However, constant propagation and inlining seem to be powerful enough to handlepromote_rule
, so that's what I've implemented here. Perhaps some inlines are unnecessary.I haven't had time to test this thoroughly for inference/performance (hence the WIP) but I'm having trouble judging if this is a terrible idea for some reason (hence the RFC). Nanosoldier might shed some light...
ref: https://discourse.julialang.org/t/limitations-to-the-fix-of-265/3613